const mongoose = require('mongoose');
const slugify = require('slugify');
const validator = require('validator');
//const User = require('./userModel')
const tourSchema = new mongoose.Schema({
    name: {
        type: String,
        required: [true, 'A Tour must have a name'],
        unique: true,
        trim: true,
        maxlength: [40, '最长为40'],
        minlength: [10, '最少为10个'],
        //validate:[validator.isAlpha,'Tour name must only contain characters']
    },
    slug: {
        type: String,
    },
    duration: {
        type: Number,
        required: [true, 'A tour must have a duration']
    },
    maxGroupSize: {
        type: Number,
        required: [true, 'A tour must have a difficulty']
    },
    difficulty: {
        type: String,
        required: [true, 'A tour must have a difficulty'],
        enum: {
            values: ['easy', 'medium', 'difficult'],
            message: 'Difficulty is either esay medium difficult'
        }
        //限制值只能为枚举
    },
    ratingsAverage: {
        type: Number,
        default: 4.5,
        min: [1, 'Rating must be above 1.0'],
        max: [5, 'Rating must be below 5.0']
    },
    ratingsQuantity: {
        type: Number,
        default: 4.5
    },
    price: {
        type: Number,
        required: [true, 'A Tour muse have a price']
    },
    priceDiscount: {
        type: Number,
        validate: {
            validator: function (val) {
                // 只能用于创建新的文档 更新的时候似乎比启用
                return val < this.price
            },
            message: 'Discount price ({VALUE} should be below regular price'
        }
    },
    summary: {
        type: String,
        trim: true, // 删除所有的空白
        required: [true, 'A tour must have a description'],
    },
    description: {
        type: String,
        trim: true,
    },
    imageCover: {
        type: String,
        required: [true, 'A tour must have a cover image'],
    },
    images: [String],
    createdAt: {
        type: Date,
        default: Date.now(),
        select: false, // 屏蔽 不会把该字段折返给请求体
    },
    startDates: [Date],
    secretTour: {
        type: Boolean,
        default: false,
    },
    // 地址信息
    startLocations: {
        type: {
            type: String,
            default: 'Point',
            enum: ['Point']
        },
        coordinates: [Number],
        address: String,
        description: String,
    },
    locations: [{
        type: {
            type: String,
            default: 'Point',
            enum: ['Point']
        },
        coordinates: [Number],
        address: String,
        description: String,
        day: Number
    }],
    // 导游数据
    //guides:Array,
    // 引用模式
    guides: [{
        type: mongoose.Schema.ObjectId,
        ref: 'User'// 引用的模型来源
    }]
},
{
    toJSON: {
        virtuals: true
    },
    toObject: {
        virtuals: true
    }
}
);
// 1升序 -1降序 提前建立索引可以查的更快
tourSchema.index({price:1,ratingsAverage:-1});
tourSchema.index({slug:1});
// 匿名函数的this指向 虚拟填充
tourSchema.virtual('durationWeeks').get(function () {
    return this.duration / 7
})
// 虚拟填充 将两个模型连接在一起
tourSchema.virtual('reviews',{
    ref:"Review",
    foreignField:'tour',
    localField:'_id'
})
// 文档中间件 运行在 save和create之前 不会在更新的时候启用
// tourSchema.pre('save',function(next){
//     this.slug = slugify(this.name, {lower:true});
//     next();
// })
// tourSchema.pre('save',function(next){
//     console.log('文档即将保存');
//     next();
// })
// tourSchema.post('save',function(doc,next){
//     console.log(doc);
//     next();
// })
// 解析用户的ID
// tourSchema.pre('save',async function(next){
//     const guidesPromises = this.guides.map(async id => await User.findById(id));
//     this.guides = await Promise.all(guidesPromises);
//     next();
// })
// query 中间件 确切的说是钩子函数
// 过滤掉secreTour字段的数据
tourSchema.pre(/^find/, function (next) {
    this.find({
        secretTour: {
            $ne: true
        }
    });
    this.start = Date.now();
    next()
})
// 自动天聪guides字段并且隐藏掉select里的字段 guides是根据id查找出的用户
tourSchema.pre(/^find/, function (next) {
    this.populate({
        path: 'guides',
        select: '-__v -passwordChangedAt'
    })
    next()
})

tourSchema.post(/^find/, function (docs, next) {
    console.log(`花费了${Date.now() - this.start}ms`)
    //console.log(docs);
    next();
})

// aggregation 中间件
tourSchema.pre('aggregate', function (next) {
    this.pipeline().unshift({
        $match: {
            secretTour: {
                $ne: true
            }
        }
    }); // 清除秘密旅游字段为true的数据
    console.log(this.pipeline, '管道中间件');
    next();
})
const Tour = mongoose.model('Tour', tourSchema);

module.exports = Tour;